import java.util.*;

public class PlayerSkeleton {
	public static Random r;
	public static int pieceMasks[][];
	public static int masks[];

	public static double[] coe = { 0.8947487403840866, 0.20860689876950692, 0.5570533100063562, 0.3222138561046688, 0.1964557940966854, 0.5621767558135445};

	//implement this function to have a working system
	public static int pickMove(State s, int[][] legalMoves) {
		int[][] board = s.getField();

		int[] top = s.getTop();
		int[][][] pBottom = State.getpBottom();
		int[][][] pTop = State.getpTop();
		int[][] pWidth = State.getpWidth();
		int[][] pHeight = State.getpHeight();
		int nextPiece = s.getNextPiece();
		int best = 0;
		double bh = Double.MAX_VALUE, bt = 999;
		for(int i = 0; i < legalMoves.length; i++){
			int orient = legalMoves[i][0];
			int slot = legalMoves[i][1];
			int height = top[slot]-pBottom[nextPiece][orient][0];
			int pw = pWidth[nextPiece][orient];
			int[] bottoms = pBottom[nextPiece][orient];
			int ph = pHeight[nextPiece][orient];
			int[] tops = pTop[nextPiece][orient];
			for(int c = 1; c < pw; c++) {
				height = Math.max(height,top[slot+c]-bottoms[c]);
			}
			if(height+ph >= State.ROWS)continue;
			int touchwall = 0;
			if(slot == 0){
				touchwall += tops[0] - bottoms[0];
			}else if(slot + pw == State.ROWS){
				touchwall += tops[pw - 1] - bottoms[pw - 1];
			}
			for(int j = 0; j < pw; j++) {
				for(int h = height+bottoms[j]; h < height+tops[j]; h++) {
					board[h][j+slot] = -1;
				}
			}
			int rowsCleared = 0;
			int cleared = 0;
			for(int r = height+ph-1; r >= height; r--) {
				boolean full = true;
				for(int c = 0; c < State.COLS; c++) {
					if(board[r][c] == 0) {
						full = false;
						break;
					}
				}
				//if the row was full - remove it and slide above stuff down
				if(full) {
					rowsCleared++;
					cleared |= 1<<(height+ph-1 -r);
				}
			}

			int hh = 0, block = 0;
			// int nhh = 0;

			// for(int r = height+ph-1; r >= height && r > 0; r--) {
			// 	if((cleared & (1<<(height+ph-1 -r))) > 0){
			// 		for(int j = 0; j < State.COLS; j++) {
			// 			int hhh = r - 1;
			// 			while(hhh >= 0 && board[hhh][j] == 0){
			// 				hhh--;
			// 				nhh--;
			// 			}
			// 		}
			// 		continue;
			// 	}
			// 	for(int j = 0; j < pw; j++) {
			// 		if(board[r - 1][j + slot] == 0){
			// 			int hhh = r - 1;
			// 			while(hhh >= 0 && board[hhh][j + slot] <= 0){
			// 				if(board[hhh][j + slot] < 0){
			// 					if((cleared & (1<<(height+ph-1 -hhh))) > 0){
			// 						hhh--;
			// 						continue;
			// 					}else{
			// 						break;
			// 					}
			// 				}
			// 				hh++;
			// 				hhh--;
			// 			}
			// 		}
			// 	}
			// }
			for(int j = 0; j < State.COLS; j++){
				int r = 0;
				int curhole = 0;
				boolean hasHole = false;
				int t = top[j];
				if(j >= slot && j < (slot + pw)){
					t = height + tops[j - slot];
				}
				while(r < t){
					if(board[r][j] != 0){
						hasHole = true;
						curhole++;
					}else{
						if((cleared & (1<<(height+ph-1 -r))) > 0){
							continue;
						}
						if(hasHole){
							hh += curhole;
							block++;
							curhole = 0;
						}
					}
					r++;
				}
			}

			for(int j = 0; j < pw; j++) {
				for(int h = height+bottoms[j]; h < height+tops[j]; h++) {
					board[h][j+slot] = 0;
				}
			}
			int maxh = 0;
			int sum = 0, sqsum = 0;
			for(int c = 0; c < top.length; c++){
				int h;
				if(c >= slot && c < pw){
					h = height + tops[c - slot];
				}else{
					h = top[c];
				}
				sum += h;
				sqsum += h * h;
				maxh = Math.max(h, maxh);
			}
			maxh -= rowsCleared;
			double sd = Math.pow((double)sqsum / top.length - Math.pow((double)sum / top.length, 2),0.5);
			double val = h(height, sd, hh, -rowsCleared * 10, block, -touchwall);
			if(val < bh){
				best = i;
				bh = val;
			}
		}

		return best;
	}

	private static double h(int height, double sd, int holes, int rowsCleared, int block, int touchWall){
		return coe[0] * (double)height + Math.pow(holes, 1) * coe[2] + coe[3] * sd + coe[4] * touchWall + rowsCleared * coe[1]
			+ block * coe[5];
	}
	
	public static void main(String[] args) {
		int max = 0, min = 99999;
		int iter = 1000;
		while(iter-->0){
			State s = new State(){
				// @Override
				// public void draw(){

				// }

				// @Override
				// public void drawNext(int slot, int orient) {
				// }
			};
			TFrame tf = new TFrame(s);
			PlayerSkeleton p = new PlayerSkeleton();
			r = new Random();
			while(!s.hasLost()) {
				s.makeMove(p.pickMove(s,s.legalMoves()));
				s.draw();
				s.drawNext(0,0);
				// try {
				// 	Thread.sleep(100);
				// } catch (InterruptedException e) {
				// 	e.printStackTrace();
				// }
			}
			tf.dispose();
			System.out.println("You have completed "+s.getRowsCleared()+" rows.");
			max = Math.max(max, s.getRowsCleared());
			min = Math.min(min, s.getRowsCleared());
			System.out.println("Max: " + max + ", Min: " + min);
		}
	}
	
}
